unit Unit1;
//mironix-light-x

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Rtti;

type
  TForm1 = class(TForm)
    Btn_ShowRttiInfo: TButton;
    Memo1: TMemo;
    Btn_CallRttiMethod: TButton;
    procedure Btn_ShowRttiInfoClick(Sender: TObject);
    procedure Btn_CallRttiMethodClick(Sender: TObject);
  private
    Ref:TRttiContext;
  public
    procedure ExportRtti(AClass:TRttiinstanceType);
  end;

  TRttiDemo=class(TObject)
  private
    FX:integer;
    FY:integer;
    FStr:string;
    function GetXY:integer;
  public
    function  DoAdd(X,Y:integer):integer;
    procedure ShowMagBox;
  public
    property X:integer read FX write FX;
    property Y:integer read FY write FY;
    property Str:string read FStr write FStr;
    property XY:integer read GetXY;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.Btn_CallRttiMethodClick(Sender: TObject);
var
  ARttiDemo:TRttiDemo;
  AType    :TRttiType;
  AValue   :TValue;
  AMethod  :TRttiMethod;
begin
  ARttiDemo:=TRttiDemo.Create;
  ARttiDemo.ShowMagBox;

  AType    :=Ref.GetType(TRttiDemo);
  AMethod  :=AType.GetMethod('DoAdd');
  if AMethod=nil  then Exit;

  AValue   :=AMethod.Invoke(ARttiDemo,[1,2]);
  ShowMessageFmt('%d',[AValue.AsInteger]);



  //YXC_2011_04_14_20_42_37
  AMethod:=AType.GetMethod('ShowMagBox');
  AMethod.Invoke(ARttiDemo,[]);

  ARttiDemo.Free;
end;

procedure TForm1.Btn_ShowRttiInfoClick(Sender: TObject);
var
  AType:TRttiType;
begin
  AType:=Ref.GetType(TRttiDemo);
  ExportRtti(AType.AsInstance);
end;

procedure TForm1.ExportRtti(AClass: TRttiinstanceType);
var
  Fields:TArray<TRttiField>;
  Field :TRttiField;

  Methods:TArray<TRttiMethod>;
  Method :TRttiMethod;

  Params :TArray<TRttiParameter>;
  Param  :TRttiParameter;

  Props  :TArray<TRttiProperty>;
  Prop   :TRttiProperty;

  S      :string;
begin
  Memo1.Lines.Clear;
  //Memo1.Lines.Add(AClass.Name);

  Fields:=AClass.GetFields;
  Memo1.Lines.Add('Fields');
  for Field in Fields do
  begin
    Memo1.Lines.Add(Format('    %s:%s',[Field.Name,Field.FieldType.Name]));
  end;

  Methods:=AClass.GetMethods;
  Memo1.Lines.Add('Methods');
  for Method in Methods do
  begin
    Params:=Method.GetParameters;
    S:='';
    for Param in Params do
    begin
      S:=S+Format('  %s,',[Param.ToString]);
    end;
    S:=Copy(S,1,Length(s)-2);
    if Method.ReturnType=nil  then
    begin
      S:=Format('    procedure %s(%s);',[Method.Name,S]);
    end else
    begin
      S:=Format('    function  %s(%s):%s;',[Method.Name,S,Method.ReturnType.Name]);
    end;
    Memo1.Lines.Add(S);
  end;


  Props:=AClass.GetProperties;
  Memo1.Lines.Add('Properties');
  for Prop in Props do
  begin
    S:='';
    if (Prop.IsReadable) and (not Prop.IsWritable) then
    begin
      S:='Read Only';
    end;
    if (Prop.IsWritable) and (not Prop.IsReadable) then
    begin
      S:='Write Only';
    end;
    Memo1.Lines.Add(Format('    %s:%s;%s',[Prop.Name,Prop.PropertyType.Name,S]));
  end;
end;

{ TRttiDemo }

function TRttiDemo.DoAdd(X, Y: integer): integer;
begin
  Result:=X+Y;
end;

function TRttiDemo.GetXY: integer;
begin
  Result:=FX+FY;
end;

procedure TRttiDemo.ShowMagBox;
begin
  ShowMessage('The Rtti Demo');
end;

end.
